home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
gnuish
/
cpio11as
/
copyout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-22
|
8KB
|
282 lines
/* copyout.c - cpio copy out sub-function.
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
This port is also distributed under the terms of the
GNU General Public License as published by the
Free Software Foundation.
Please note that this file is not identical to the
original GNU release, you should have received this
code as patch to the official release.
$Header: e:/gnu/cpio/RCS/copyout.c 1.1.0.2 90/09/23 23:33:23 tho Exp $
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef S_IFLNK
#define lstat stat
#endif
#include <errno.h>
#ifndef MSDOS /* sigh, it's `volatile' !!! */
extern int errno;
#endif
#include <fcntl.h>
#ifndef MSDOS
#include <sys/file.h>
#endif
#ifdef USG
#include <time.h>
#include <string.h>
#else
#include <sys/time.h>
#include <strings.h>
#endif
#include "cpio.h"
#include "dstring.h"
#include "extern.h"
/* Write out header FILE_HDR, including the file name, to file
descriptor OUT_DES. */
void
write_out_header (file_hdr, out_des)
struct cpio_header *file_hdr;
int out_des;
{
if (portability_flag)
{
char ascii_header[78];
sprintf (ascii_header,
#ifdef MSDOS
"%06ho%06ho%06ho%06ho%06ho%06ho%06ho%06ho%011lo%06ho%011lo",
#else
"%06o%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o",
#endif
file_hdr->h_magic & 0xFFFF, file_hdr->h_dev & 0xFFFF,
file_hdr->h_ino & 0xFFFF, file_hdr->h_mode & 0xFFFF,
file_hdr->h_uid & 0xFFFF, file_hdr->h_gid & 0xFFFF,
file_hdr->h_nlink & 0xFFFF, file_hdr->h_rdev & 0xFFFF,
file_hdr->h_mtime, file_hdr->h_namesize & 0xFFFF,
file_hdr->h_filesize);
copy_buf_out (ascii_header, out_des, 76);
/* Write file name to output. */
copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
}
else
{
/* Word align the output. */
if (output_size & 1)
copy_buf_out ("", out_des, 1);
#ifdef MSDOS
file_hdr->h_mtimes[0] = (unsigned int) (file_hdr->h_mtime >> 16);
file_hdr->h_mtimes[1] = (unsigned int) (file_hdr->h_mtime & 0xFFFF);
file_hdr->h_filesizes[0]
= (unsigned int) (file_hdr->h_filesize >> 16);
file_hdr->h_filesizes[1]
= (unsigned int) (file_hdr->h_filesize & 0xFFFF);
#else /* not MSDOS */
file_hdr->h_mtimes[0] = file_hdr->h_mtime >> 16;
file_hdr->h_mtimes[1] = file_hdr->h_mtime & 0xFFFF;
file_hdr->h_filesizes[0] = file_hdr->h_filesize >> 16;
file_hdr->h_filesizes[1] = file_hdr->h_filesize & 0xFFFF;
#endif /* not MSDOS */
/* Output the file header. */
copy_buf_out ((char *) file_hdr, out_des, 26);
/* Write file name to output. */
copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
/* Word align the output. */
if (file_hdr->h_namesize % 2)
copy_buf_out ("", out_des, 1);
}
}
/* Read a list of file names from the standard input
and write a cpio collection on the standard output.
The format of the header depends on the compatibility (-c) flag. */
void
process_copy_out ()
{
int res; /* Result of functions. */
dynamic_string input_name; /* Name of file read from stdin. */
long times[2]; /* For resetting file times after copy. */
struct stat file_stat; /* Stat record for file. */
struct cpio_header file_hdr; /* Output header information. */
int in_file_des; /* Source file descriptor. */
int out_file_des; /* Output file descriptor. */
#ifdef MSDOS
setmode (fileno (stdout), O_BINARY);
#endif
/* Initialize copy out. */
ds_init (&input_name, 128);
file_hdr.h_magic = 070707;
/* Check whether the output file might be a tape. */
out_file_des = fileno (stdout);
if (fstat (out_file_des, &file_stat))
error (1, errno, "standard output is closed");
#ifdef S_IFBLK
output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR
|| (file_stat.st_mode & S_IFMT) == S_IFBLK);
#else /* not S_IFBLK */
output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR);
#endif /* not S_IFBLK */
output_is_seekable = ((file_stat.st_mode & S_IFMT) == S_IFREG);
/* Copy files with names read from stdin. */
while (ds_fgets (stdin, &input_name) != NULL)
{
/* Check for blank line. */
if (input_name.ds_string[0] == 0)
{
error (0, 0, "blank line ignored");
continue;
}
/* Process next file. */
if ((*xstat) (input_name.ds_string, &file_stat) < 0)
error (0, errno, "%s", input_name.ds_string);
else
{
/* Set values in output header. */
file_hdr.h_dev = file_stat.st_dev;
file_hdr.h_ino = file_stat.st_ino;
file_hdr.h_mode = file_stat.st_mode;
file_hdr.h_uid = file_stat.st_uid;
file_hdr.h_gid = file_stat.st_gid;
file_hdr.h_nlink = file_stat.st_nlink;
file_hdr.h_rdev = file_stat.st_rdev;
file_hdr.h_mtime = file_stat.st_mtime;
file_hdr.h_filesize = file_stat.st_size;
file_hdr.h_namesize = ds_strlen (&input_name) + 1;
file_hdr.h_name = input_name.ds_string;
/* Copy the named file to the output. */
switch (file_hdr.h_mode & S_IFMT)
{
case S_IFREG:
#ifdef MSDOS
in_file_des = open (input_name.ds_string,
O_RDONLY | O_BINARY, 0);
#else
in_file_des = open (input_name.ds_string, O_RDONLY, 0);
#endif
if (in_file_des < 0)
{
error (0, errno, "%s", input_name.ds_string);
continue;
}
write_out_header (&file_hdr, out_file_des);
copy_files (in_file_des, out_file_des, file_hdr.h_filesize);
close (in_file_des);
if (reset_time_flag)
{
times[0] = file_stat.st_atime;
times[1] = file_stat.st_mtime;
if (utime (file_hdr.h_name, times) < 0)
error (0, errno, "%s", file_hdr.h_name);
}
break;
case S_IFDIR:
file_hdr.h_filesize = 0;
write_out_header (&file_hdr, out_file_des);
break;
case S_IFCHR:
#ifdef S_IFBLK
case S_IFBLK:
#endif
#ifdef S_IFSOCK
case S_IFSOCK:
#endif
#ifdef S_IFIFO
case S_IFIFO:
#endif
file_hdr.h_filesize = 0;
write_out_header (&file_hdr, out_file_des);
break;
#ifdef S_IFLNK
case S_IFLNK:
{
char *link_name = (char *) xmalloc (file_stat.st_size);
if (readlink (input_name.ds_string, link_name,
file_stat.st_size) < 0)
{
error (0, errno, "%s", input_name.ds_string);
free (link_name);
continue;
}
write_out_header (&file_hdr, out_file_des);
copy_buf_out (link_name, out_file_des, file_stat.st_size);
free (link_name);
}
break;
#endif
default:
error (0, 0, "%s: unknown file type", input_name.ds_string);
}
if (verbose_flag)
fprintf (stderr, "%s\n", input_name.ds_string);
}
}
/* The collection is complete; append the trailer. */
file_hdr.h_filesize = 0;
file_hdr.h_namesize = 11;
file_hdr.h_name = "TRAILER!!!";
write_out_header (&file_hdr, out_file_des);
/* Fill up the output block. */
while (output_size < io_block_size)
{
copy_buf_out (output_buffer, out_file_des,
(2 * output_size < io_block_size) ?
output_size : io_block_size - output_size);
}
empty_output_buffer (out_file_des);
finish_output_file ("standard output", out_file_des);
#ifdef MSDOS
res = (int) (output_bytes / io_block_size);
#else
res = output_bytes / io_block_size;
#endif
if (res == 1)
fprintf (stderr, "1 block\n");
else
fprintf (stderr, "%d blocks\n", res);
}